﻿using Polly;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Common
{
    public class Retry : DemoBase
    {
        public override string DemoName => "Polly-Retry Demo";

        /// <summary>
        /// 老板开出工资
        /// </summary>
        int SalaryFromBoss = 10_000;

        public override void RunDemo()
        {
            base.Init();
            try
            {
                int retryTimes = 5;

                var retryTwoTimesPolicy = Policy
                    .Handle<SalaryException>()      //支持的第1种异常类型
                    .Or<TimeException>()            //支持的第2种异常类型
                    .Or<Exception>(ex => ex.Message == "攻城狮有点犹豫")   //注意这个限定 这个根据业务场景 有很大灵活运用空间
                                                                    //.OrInner<Exception>()         //不再赘述
                                                                    //.RetryForever();<Exception>() //不再赘述
                                                                    //.WaitAndRetry(new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(4) }
                    .Retry(retryTimes, (ex, onRetry) =>
                    {
                        PrintInfo($"攻城狮说:{ex.Message}");
                        PrintInfo($"第{onRetry}次谈心（薪）失败 老板得重新谈\n");
                        老板调薪();
                    });
                retryTwoTimesPolicy.Execute(() =>
                {
                    与老板谈心();
                    PrintSuccess("谈心成功");
                });
            }
            catch (Exception e)
            {
                PrintError($"超出老板的预料：{e.Message}");
            }
        }

        private void 老板调薪()
        {
            SalaryFromBoss = SalaryFromBoss + 10_000;
            PrintInfo($"与老板谈心 给出薪资{SalaryFromBoss}");
        }

        private void 与老板谈心()
        {

            if (SalaryFromBoss < 20_000)
            {
                throw new TimeException($"天天都在加班，世界那么大，我想去走走。");
            }
            if (SalaryFromBoss < 30_000)
            {
                throw new SalaryException(SalaryFromBoss, $"薪资太少，您没别的事，我回去写Bug了！");
            }
            if (SalaryFromBoss < 40_000)
            {
                if (DateTime.Now.Second % 2 == 0)
                    throw new Exception("攻城狮有点犹豫");
                else
                    throw new Exception("攻城狮没接电话 这下没法谈了");//这个指定类型和场景之外的异常 不会出发重试机制
            }
            PrintInfo($"攻城狮说：我这就回去赶进度~");
        }
    }

    class SalaryException : Exception
    {
        int Salary { get; set; }

        public SalaryException(int salary, string message) : base(message)
        {
            Salary = salary;
        }
    }

    class TimeException : Exception
    {
        public TimeException(string message) : base(message)
        {

        }
    }
}
